新开源 Spring Boot Starter Jt808 已经有一段时间了,新版本已经支持了 2011
、2013
、2019
版本的协议解析,并完善了自定义消息的功能,还是值得期待的。
本文主要说明 Spring Boot Starter Jt808 的启动流程,配置项以及一些细节,读懂本文需要先了解字节码和 SpringBoot
等技术知识。
启动服务
项目依赖 SpringBoot
,所以启动按照 Spring
的逻辑需要有一个启动注解。于是我们先从 EnableJt808Server
这个注解开始。
1 | // ... |
EnableJt808Server
通过 Import
注解引入了 Jt808Starter
、Jt808Config
、SimpleBeanConfig
三个 Bean,我们依次看一下这三个 Bean 都是什么作用。
Jt808Config
顾名思义,Jt808Config
是用来承载 jt808 服务的配置的,关于配置项的详细信息可以在下文中找到。这里只说明这个类的作用。
配置类使用直接赋值的方式为配置项添加默认值。
SimpleBeanConfig
1 | // ... |
在 1.2.2 版本里为了简化用户入门难度增加了默认 Bean 配置,所以用户如果不定义缓存 Bean CacheService
的话应该会有默认的 Bean 顶替,但是持久化服务还是需要用户提供的,默认提供的Bean DataService
是不能接收消息的,只是能够保证启动成功。同时用户的主要业务逻辑也是在 DataService
实现类里。
- 系统里默认提供了基于
ConcurrentHashMap
的缓存。 - 数据层提供的类仅仅是添加了日志记录而已,并且不能通过任何客户端的鉴权。
Jt808Starter
这里定义了启动逻辑,首先定义了处理持久化需要的线程池,线程命名使用 jt808-mina-thread-pool-db
前缀,方便调试。
然后是加载 com.zhoyq.server.jt808.starter
包下的所有 Bean。
再次是程序启动事件 ApplicationStartedEvent
程序启动成功后会运行 onApplicationEvent
方法中的逻辑。
- 检查是否启用 Jt808 服务。
- 获取数据库中的历史数据,并存储到缓存中。
- 获取用户配置使用的底层服务实现(Mina或者Netty),并启动。
这里需要注意的是,在启动完成后
PackHandlerManagement
也处理了一部分启动逻辑,这里把消息包处理器全部收集起来并存储到缓存中待用。
下面就是 Mina
或者 Netty
的启动了。
Mina
启动的时候,加载的关于编码解码的工厂类是 Jt808CodecFactory
,这里定义了处理消息包边界的方法逻辑。Netty
启动的时候,加载的解码器和编码器是 Jt808NettyDecoder
、Jt808NettyEncoder
,同样是处理消息边界的方法和逻辑。
这里由于编码解码没有进一步封装,会有部分源码重复,会在后期优化的时候处理掉。
下面是核心逻辑:
1 | // 有数据进入 开始读取数据 |
解码器处理的简单逻辑:
- 当接收到的消息刚好时,截断,继续接收下一批内容。
- 当接收到的消息不够时,等下一批数据拼接在当前数据之后继续读取。
- 当接收到的消息太多时,读取一个消息包完成后,截断,进行下一次读取。
到此底层服务也配置启动了。
配置选项
下面是目前可用的配置注释。
1 | private String use = "mina"; // 使用框架 默认 mina 可选 netty |
消息处理
下面是消息在下方到用户处理逻辑前的核心逻辑:
1 | // 按照协议解析相应数据位的字节码 |
- 消息先查看是否分包,分包则先不解析,待接收完整(接收到最后一包数据之后,会检查数据完整性,如果不完整会下发重传指令,如果完整)再解析;消息未分包则直接解析。
- 消息解析时,交由对应消息ID的消息包处理器进行处理。
- 消息解析时,会检查鉴权,如果没有鉴权仅能访问终端注册和终端鉴权两个消息包。
- 消息包处理的逻辑都在
com.zhoyq.server.jt808.starter.pack
包下,希望了解更多的,可以直接查看源代码。 - 默认处理方式中,所有查询应答类消息都会通过持久化接口的
terminalAnswer
方法存储,待进一步查询。
2019 兼容性处理逻辑
v1.2.2 版本增加了 2019 版本协议的解析内容,关于兼容性处理有以下几点:
- 消息体属性中的版本标识位,为2019版本独有。
- 2019 版本电话号码长度增加了,大部分兼容性可以通过电话号码位数判断。
- 部分消息ID是2019独有的所以可以单独处理。
- 终端注册和驾驶员身份信息上报可以根据消息长度可以判断是2013还是2011版本协议。
帮助类
帮助类处理了大部分底层逻辑,有兴趣可以看相关源码,帮助类可以使用 @Autowired 注解直接引入。
- ByteArrHelper(二进制处理帮助类)
- Jt808Helper(协议逻辑相关帮助类)
- ResHeler(应答消息类)
关于开源
推荐邮件(feedback#zhoyq.com)或者使用 ISSUE
(包括GITHUB和GITEE) 这两种方式报告 BUG
,我会第一时间修复。